﻿#region header

//  ***************************************************************************
// *                                LICENSE
//  ***************************************************************************
//  * "Haplous" .NET Simple 2D Game Framework
//  * 
//  * Copyright © Jonathan Evans 2014-2014
//  * 
//  * This program is free software; you can redistribute it and/or
//  * modify it under the terms of the GNU General Public License
//  * as published by the Free Software Foundation; either version 2
//  * of the License, or (at your option) any later version.
//  * 
//  * This program is distributed in the hope that it will be useful,
//  * but WITHOUT ANY WARRANTY; without even the implied warranty of
//  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  * GNU General Public License for more details.
//  * 
//  * You should have received a copy of the GNU General Public License
//  * along with this program; if not, write to the Free Software
//  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//  * 
//  ***************************************************************************
//  * 
//  * Contact: opencollar@googlemail.com
//  * 
//  * Website: http://haplous.codeplex.com/
//  *
//  * NuGet:   http://www.nuget.org/packages/haplous/
//  *
//  * File:    Haplous/Haplous/Visualization.cs
//  *
//  ***************************************************************************

#endregion

using System.Diagnostics;

using Haplous.Core;

namespace Haplous
{
    /// <summary>
    ///     A class describing the ways in which a element is visualized. This class cannot be inherited.
    /// </summary>
    [DebuggerDisplay("Visualization: Scaling={Scaling}; Tiling={Tiling}; Visible={Visible}; Origin={Origin}")]
    public sealed class Visualization : NotifyObject, IProperty<Visualization>
    {
        /// <summary>
        ///     Specifies the position of the picture if it is unscaled or tiled.
        /// </summary>
        private OriginKind _origin;

        /// <summary>
        ///     Specifies how the picture is scaled.
        /// </summary>
        private PictureScalingKind _scaling;

        /// <summary>
        ///     Determines the way in which tiled pictures repeat.
        /// </summary>
        private TileKind _tiling;

        /// <summary>
        ///     Determines whether the element is visible.
        /// </summary>
        private bool _visible = true;

        /// <summary>
        ///     Determines whether the element is visible.  <see langword="true" /> by default.
        /// </summary>
        public bool Visible
        {
            get { return _visible; }
            set { OnPropertyChanged("Visible", ref _visible, value); }
        }

        /// <summary>
        ///     Specifies how the picture is scaled.
        /// </summary>
        public PictureScalingKind Scaling
        {
            get { return _scaling; }
            set { OnPropertyChanged("Scaling", ref _scaling, value); }
        }

        /// <summary>
        ///     Specifies the position of the picture if it is unscaled or tiled.
        /// </summary>
        public OriginKind Origin
        {
            get { return _origin; }
            set { OnPropertyChanged("Origin", ref _origin, value); }
        }

        /// <summary>
        ///     Determines the way in which tiled pictures repeat.
        /// </summary>
        public TileKind Tiling
        {
            get { return _tiling; }
            set { OnPropertyChanged("Tiling", ref _tiling, value); }
        }

        /// <summary>
        ///     Copies the value of the specified property object into the current property object.
        /// </summary>
        /// <param name="property">The property object from which to copy the value.</param>
        public void Copy(IProperty<Visualization> property)
        {
            var visualization = (Visualization)property;

            Origin = visualization.Origin;
            Scaling = visualization.Scaling;
            Tiling = visualization.Tiling;
            Visible = visualization.Visible;
        }
    }

    /// <summary>
    ///     The way in which a tiled picture should be repeated on an element.
    /// </summary>
    public enum TileKind
    {
        /// <summary>
        ///     The picture should not be repeated (the same as setting <see cref="Visualization.Scaling" /> to
        ///     <see cref="PictureScalingKind.Original" />).
        /// </summary>
        None = 0,

        /// <summary>
        ///     The picture is repeated horizontally (starting at the position specified in <see cref="Visualization.Origin" />)
        ///     and will be repeated to the left and right of that position.
        /// </summary>
        HorizontalRepeat,

        /// <summary>
        ///     The picture is repeated vertically (starting at the position specified in <see cref="Visualization.Origin" />) and
        ///     will be repeated above and below that position.
        /// </summary>
        VerticalRepeat,

        /// <summary>
        ///     The picture is repeated horizontally and vertically (starting at the position specified in
        ///     <see cref="Visualization.Origin" />) and will be repeated in all directions from that position.
        /// </summary>
        HorizontalAndVerticalRepeat
    }

    /// <summary>
    ///     Defines the position of an unscaled image inside it's containing element.
    /// </summary>
    public enum OriginKind
    {
        /// <summary>
        ///     The center of the image is positioned over the center of the containing element.
        /// </summary>
        Center = 0,

        /// <summary>
        ///     The top-middle of the image is positioned over the top-middle of the containing element.
        /// </summary>
        Top,

        /// <summary>
        ///     The top-right of the image is positioned over the top-right of the containing element.
        /// </summary>
        TopRight,

        /// <summary>
        ///     The center-right of the image is positioned over the center-right of the containing element.
        /// </summary>
        Right,

        /// <summary>
        ///     The bottom-right of the image is positioned over the bottom-right of the containing element.
        /// </summary>
        BottomRight,

        /// <summary>
        ///     The bottom-middle of the image is positioned over the bottom-middle of the containing element.
        /// </summary>
        Bottom,

        /// <summary>
        ///     The bottom-left of the image is positioned over the bottom-left of the containing element.
        /// </summary>
        BottomLeft,

        /// <summary>
        ///     The center-left of the image is positioned over the center-left of the containing element.
        /// </summary>
        Left,

        /// <summary>
        ///     The top-left of the image is positioned over the top-left of the containing element.
        /// </summary>
        TopLeft
    }

    /// <summary>
    ///     Defines the type of scaling that should be applied to pictures.
    /// </summary>
    public enum PictureScalingKind
    {
        /// <summary>
        ///     The picture should be displayed at its natural size, with regions clipped or transparent if the element containing
        ///     the picture is of a different size.
        /// </summary>
        /// <remarks>Used in conjunction with the <see cref="Visualization.Origin" /> property.</remarks>
        Original = 0,

        /// <summary>
        ///     The picture will be scaled (stretched or compressed) to fit the element on which it is being displayed.
        /// </summary>
        Stretch,

        /// <summary>
        ///     The picture will be tiled (repeated) to fit the element on which it is being displayed.
        /// </summary>
        /// <remarks>
        ///     Used in conjunction with the <see cref="Visualization.Origin" /> and <see cref="Visualization.Tiling" />
        ///     properties.
        /// </remarks>
        Tile
    }
}